# -*- coding: utf-8 -*-  
#!/usr/bin/env python

import urllib2
import urllib
import os
import re
import sys
import threading
import threading
import ctypes
from pydispatch import dispatcher
 
 
def _async_raise(tid, excobj):
    res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(excobj))
    if res == 0:
        raise ValueError("nonexistent thread id")
    elif res > 1:
        # """if it returns a number greater than one, you're in trouble, 
        # and you should call it again with exc=NULL to revert the effect"""
        ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, 0)
        raise SystemError("PyThreadState_SetAsyncExc failed")
 
class Thread(threading.Thread):
    def raise_exc(self, excobj):
        assert self.isAlive(), "thread must be started"
        for tid, tobj in threading._active.items():
            if tobj is self:
                _async_raise(tid, excobj)
                return
        
        # the thread was alive when we entered the loop, but was not found 
        # in the dict, hence it must have been already terminated. should we raise
        # an exception here? silently ignore?
    
    def terminate(self):
        # must raise the SystemExit type, instead of a SystemExit() instance
        # due to a bug in PyThreadState_SetAsyncExc
        self.raise_exc(SystemExit)
## end of http://code.activestate.com/recipes/496960/ }}}

class DownloadThread(Thread):
  def __init__(self, ringtongInfos):
    threading.Thread.__init__(self)
    self._ringtongInfos=ringtongInfos
    self.cfg = {'host':'www.mytinyphone.com', 'port':80, 'fileHost':'files2.mytinyphone.com', 'datafile':'data.dat', 'escape':'/\*?"<>|'}
    self.appExit=False
    
  def run(self):
    try:
      i=0
      for item in self._ringtongInfos:
        if item['download']=='0' and self.appExit==False and i<10:
          self.downloadFile(item)
          dispatcher.send("MSG_FILE_DOWNLOADED")
          i+=1
      
      dispatcher.send("MSG_STATE_CHANGE",dispatcher.Anonymous, 4)
    except:
      if self.appExit==False:
        dispatcher.send("MSG_NET_ERROR",dispatcher.Anonymous,-2)
      
        
  def downloadFile(self,item):
    url = 'http://'+self.cfg['fileHost']+'/file.php?fileID='+item['id']+'&type=ringt&ut_vid='
    filename=self.cur_file_dir()+'\\'+item['category']+'\\'+item['filename']
    self.ensure_dir(filename)
    urllib.urlretrieve(url, filename)
    size = str(os.path.getsize(filename)/1024+1)+'kb' 
    item['download']='1'
    item['size']=size
    
  def ensure_dir(self,f):
      d = os.path.dirname(f)
      if not os.path.exists(d):
          os.makedirs(d)  
          
  def cur_file_dir(self):
    #获取脚本路径
    path = sys.path[0]
    #判断为脚本文件还是py2exe编译后的文件，如果是脚本文件，则返回的是脚本的目录，如果是py2exe编译后的文件，则返回的是编译后的文件路径
    if os.path.isdir(path):
        return path
    elif os.path.isfile(path):
        return os.path.dirname(path)

class ParseThread(Thread):
  def __init__(self, category, pageStart=1, pageEnd=None):
    threading.Thread.__init__(self)
    self._category = category
    self._pageStart = pageStart
    self._pageEnd = pageEnd
    self.cfg = {'host':'www.mytinyphone.com', 'port':80, 'fileHost':'files2.mytinyphone.com', 'datafile':'data.dat', 'escape':'/\*?"<>|'}
    self.appExit = False
    
  def run(self):
    try:
      if self._pageEnd==None:
        self.parse(self._category,self._pageStart)
      else:
        self.parsepages(self._category, self._pageStart, self._pageEnd)
      
      #dispatcher.send("MSG_PARSE_COMPLITE")
      dispatcher.send(
        signal = "MSG_PARSE_COMPLITE"
        )
    except:
      if self.appExit==False:
        dispatcher.send("MSG_NET_ERROR",dispatcher.Anonymous,-1)
      

  def parsepages(self,category, pageStart, pageEnd):
    for page in range(pageStart,pageEnd+1):
      self.parse(category, page)
    
  def parse(self,category, page):
    source_encoding = "iso-8859-1"
    path = '/ringtones/'+category+'/?&ord=added&ordt=asc'
    if page>1:
      path += ('&start='+str((page-1)*30))
    
    opener = urllib2.build_opener()
    url =  'http://'+self.cfg['host']+path
    print url
    f = opener.open(url)
    res = f.readlines()
    p = re.compile(r'/ringtone/(\d+)"><strong>(.+)</strong>(.*)</a></td>')
    subRe = re.compile(r'<a\s*href="/search/?skey=(\w{1,})&searcht=tags">\1</a>,?\s+')
    for item in res:
      m = p.search(item)
      if m!=None:
        id=m.group(1)
        # temp = m.group(3).encode(source_encoding)
        # temp = unicode(temp, 'utf-8')
        temp = unicode(m.group(3),'ISO-8859-1')
        title=m.group(2).strip()+temp.strip()
        tags=[]
        #tagres = opener.open('http://'+cfg['host']+"/ringtone/"+id)
        # subMatch = subRe.search(tagres)
        # while subMatch!=None:
          # tags.append(subMatch.group(1))
          # subMatch = subRe.search(tagres)

        dispatcher.send("MSG_FETCH_GET_ITEM",dispatcher.Anonymous,{'id':id,'category':category,'title':title,'tags':tags,'fileUrl' : '/file.php?fileID='+id+'&type=ringt','size':0,'download':'0'})
